/*
 * @Date: 2023-03-14 17:46:56
 * @LastEditors: Chuying
 * @LastEditTime: 2023-04-03 14:09:30
 * @Description:
 */
import {
  Injectable,
  NotFoundException,
  HttpException,
  HttpStatus,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Connection, Like } from 'typeorm';
import { Posting } from './entities/posting.entity';
import { Category } from '../category/entities/category.entity';
import { CreatePostingDto } from './dto/create-posting.dto';
import { UpdatePostingDto } from './dto/update-posting.dto';
import { UserService } from './../../account/user/user.service';

@Injectable()
export class PostingService {
  constructor(
    @InjectRepository(Posting)
    private readonly PostingRepository: Repository<Posting>, // 使用泛型注入对应类型的存储库实例
    @InjectRepository(Category)
    private readonly CategoryRepository: Repository<Category>,
    private readonly connection: Connection,
    private readonly userService: UserService,
  ) {}

  async create(createPostingDto: CreatePostingDto, user: any) {
    const { username, userId } = user;
    console.log(username, userId);

    const new_posting = new Posting(); // 创建实体：要保存的数据
    // new_posting.title = createPostingDto?.title;
    new_posting.userId = userId;
    new_posting.content = createPostingDto?.content;
    new_posting.address = createPostingDto?.address;
    new_posting.images = JSON.stringify(createPostingDto?.images);
    if (createPostingDto?.categoryIds?.length) {
      const queryRunner = this.connection.createQueryRunner(); // 获取连接并创建新的queryRunner
      await queryRunner.connect(); // 使用我们的新queryRunner建立真正的数据库连
      await queryRunner.startTransaction(); // 开始事务
      try {
        // 使用事务保存到副表
        const cateList = await queryRunner.manager.findByIds(
          Category,
          createPostingDto?.categoryIds,
        );
        new_posting.categories = cateList;
        const newPosting = await this.PostingRepository.create(new_posting);
        const res = await queryRunner.manager.save(newPosting);
        console.log(res);
        await queryRunner.commitTransaction(); // 提交事务
      } catch (error) {
        console.log('创建失败，取消事务');
        await queryRunner.rollbackTransaction();
      } finally {
        await queryRunner.release();
      }
    }
    return { status: 0, result: new_posting };
  }

  // 查询所有
  async findAll(query: {
    keyWord: string;
    categoryId: number;
    page: number;
    pageSize: number;
  }) {
    const queryBuilder = this.PostingRepository.createQueryBuilder(
      'posting',
    ).leftJoinAndSelect('posting.categories', 'category');
    if (query.categoryId) {
      queryBuilder.where('category.id = :categoryId', {
        categoryId: query.categoryId,
      });
    }
    if (query.keyWord) {
      queryBuilder.andWhere(
        'LOWER(posting.title) like :keyword or LOWER(posting.content) like :keyword',
        { keyword: `%${query.keyWord.toLowerCase()}%` },
      );
    }
    queryBuilder
      .select()
      .skip(query.page ? (query.page - 1) * query.pageSize : 0)
      .take(query.pageSize);

    const [data, total] = await queryBuilder.getManyAndCount();
    const list = [];
    for (let i = 0; i < data.length; i++) {
      let obj = { userInfo: {} };
      if (data[i].images) {
        data[i].images = JSON.parse(data[i].images);
      }
      if (data[i].userId) {
        const res = await this.userService.findUserInfo(Number(data[i].userId));
        obj.userInfo = res;
      }
      obj = { ...obj, ...data[i] };
      list.push(obj);
    }
    return { list, total };
  }

  // 详情
  async findOne(id: number) {
    const res = await this.PostingRepository.findOneBy({ id });
    if (res.images) {
      res.images = JSON.parse(res.images);
    }
    return res;
  }

  // 更新
  async update(id: number, updatePostingDto: UpdatePostingDto) {
    const posting = await this.PostingRepository.findOneBy({ id });
    if (!posting) {
      //   throw new NotFoundException(`posting with ID ${id} not found`);
      throw new HttpException(
        `posting with ID ${id} not found`,
        HttpStatus.NOT_FOUND,
      );
    }
    const obj = {
      ...updatePostingDto,
      images: JSON.stringify(updatePostingDto.images),
    };

    // 更新文章分类
    if (updatePostingDto.categoryIds) {
      const cateList = await this.CategoryRepository.findByIds(
        updatePostingDto.categoryIds,
      );
      posting.categories = cateList;
    }

    Object.assign(posting, obj);

    const res = await this.PostingRepository.save(posting);
    if (res.images) {
      res.images = JSON.parse(res.images);
    }
    return res;
  }

  // 删除
  async remove(id: number) {
    return `This action removes a #${id} posting`;
  }
}
